﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using SistemaDeBastanteodePoderes.Persistencia;
using SistemaDeBastanteodePoderes.Dominio;

namespace SistemaDeBastanteodePoderes.Pruebas.DAO
{
    [TestFixture]
    public class Test_H3_1_TipoServicioDAO
    {
        ITipoServicioDAO tipoServicioDAO = null; // Utilizamos una referencia a la interfaz
        TipoServicio tipoCreado = null;

        [TestFixtureSetUp]
        public void InicializarPruebas()
        {
            tipoServicioDAO = new Persistencia.NH.TipoServicioDAO(); // Elegimos la implementación DAO a probar (ADO ó NHibernate)
            foreach (TipoServicio tipo in tipoServicioDAO.ListarTodos())
                tipoServicioDAO.Eliminar(tipo);
        }

        [Test]
        public void Test1_Crear()
        {
            TipoServicio tipoACrear = new TipoServicio();
            // 1. Validar que ocurra un error si no se ingresa el Servicio(nombre) del tipo de servicio
            tipoACrear.Servicio = null;
            Assert.Catch<Exception>(delegate
            {
                tipoCreado = tipoServicioDAO.Crear(tipoACrear);
            });

            // 2. Validar que se crea correctamente (sin error) el tipo de servicio
            tipoACrear.Servicio = "ACTIVO";
            Assert.DoesNotThrow(delegate
            {
                tipoCreado = tipoServicioDAO.Crear(tipoACrear);
            });

            // 3. Validar que se crea correctamente (sin error) un segundo tipo de servicio
            tipoACrear.Servicio = "PASIVO";
            Assert.DoesNotThrow(delegate
            {
                tipoCreado = tipoServicioDAO.Crear(tipoACrear);
            });

            // 4. Validar que el tipo creado no sea nulo, que tenga un código mayor que 0 y que el servicio sea el ingresado
            Assert.IsNotNull(tipoCreado);
            Assert.Greater(tipoCreado.Codigo, 0);
            Assert.AreEqual(tipoCreado.Servicio, tipoACrear.Servicio);
        }
        [Test]
        public void Test2_Obtener()
        {
            TipoServicio obtenido = null;
            // 1. Validar que si se intenta obtener un tipo de servicio inexistente se retorne null
            Assert.DoesNotThrow(delegate
            {
                obtenido = tipoServicioDAO.Obtener(1000);
            });
            Assert.IsNull(obtenido);
            // 2. Validar que se obtenga un tipo de servicio correctamente (sin error)
            Assert.DoesNotThrow(delegate
            {
                obtenido = tipoServicioDAO.Obtener(tipoCreado.Codigo);
            });
            Assert.IsNotNull(obtenido);
        }
        [Test]
        public void Test3_Modificar()
        {
            TipoServicio tipoAModificar = tipoServicioDAO.Obtener(tipoCreado.Codigo);
            TipoServicio tipoModificado = null;

            // 1. Validar que ocurre un error si el Servicio ingresado es nulo
            tipoAModificar.Servicio = null;
            Assert.Catch<Exception>(delegate
            {
                tipoModificado = tipoServicioDAO.Modificar(tipoAModificar);
            });

            // 2. Validar que se modifica correctamente (sin error) el tipo de servicio
            tipoAModificar.Servicio = "PATRIMONIO";
            Assert.DoesNotThrow(delegate
            {
                tipoModificado = tipoServicioDAO.Modificar(tipoAModificar);
            });

            // 3. Validar que el tipo de servicio modificado no sea nulo y el Servicio sea el ingresado
            Assert.IsNotNull(tipoModificado);
            Assert.AreEqual(tipoAModificar.Servicio, tipoModificado.Servicio);
        }
        [Test]
        public void Test4_Eliminar()
        {
            TipoServicio tipoAEliminar = tipoServicioDAO.Obtener(tipoCreado.Codigo);

            // 1. Validar que ocurra un error si se intenta eliminar un tipo de servicio inexistente
            Assert.Catch<Exception>(delegate
            {
                tipoServicioDAO.Eliminar(null);
            });
            
            // 2. Validar que se elimine un tipo de servicio correctamente
            Assert.DoesNotThrow(delegate
            {
                tipoServicioDAO.Eliminar(tipoAEliminar);
            });
            
            // 3. Validar que el tipo de servicio eliminado ya no exista
            TipoServicio tipoEliminado = tipoServicioDAO.Obtener(tipoCreado.Codigo);
            Assert.IsNull(tipoEliminado);
        }
        [Test]
        public void Test5_Listar()
        {
            tipoServicioDAO.Crear(new TipoServicio() { Servicio = "SERVICE1"});
            tipoServicioDAO.Crear(new TipoServicio() { Servicio = "SERVICE2"});

            // 1. Validar que se listen sin errores los tipos de servicios creados
            ICollection<TipoServicio> tiposExistentes = null;
            Assert.DoesNotThrow(delegate
            {
                tiposExistentes = tipoServicioDAO.ListarTodos();
            });

            // 2. Validar que retorne los 2 tipos de servicio creados
            Assert.GreaterOrEqual(tiposExistentes.Count, 2);

            // 3. Validar que la Abreviacion de cada tipo de servicio no sea nula
            foreach (TipoServicio tipo in tiposExistentes)
                Assert.IsNotNull(tipo.Servicio);
        }

        [TestFixtureTearDown]
        public void FinalizarPruebas()
        {
            foreach (TipoServicio tipo in tipoServicioDAO.ListarTodos())
                tipoServicioDAO.Eliminar(tipo);
            Persistencia.NH.NHibernateHelper.CerrarFabrica();
        }
    }
}